package com.myclass.dynamicdatasource.configuration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * Desc: 数据源管理
 *
 * @author wujw
 * @email jiwenwu@outlook.com
 * @date 2018-12-12
 */
public class DynamicDataSourceContextHolder {
    private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);

    /**
     * 用于轮循的计数器
     */
    private static int typeOnecounter = 0;
    private static int typeTwocounter = 0;

    /**
     * Maintain variable for every thread, to avoid effect other thread
     */
    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();

    // 由于有多个主库，通过代码块的方式首次放入
    {
        CONTEXT_HOLDER.set(DataSourceKey.type_one_master.name());
        CONTEXT_HOLDER.set(DataSourceKey.type_two_master.name());
    }


    /**
     * All DataSource List
     */
    public static List<Object> dataSourceKeys = new ArrayList<>();

    /**
     * The constant slaveDataSourceKeys.
     */
    public static List<Object> typeOneslaveDataSourceKeys = new ArrayList<>();
    public static List<Object> typeTwoslaveDataSourceKeys = new ArrayList<>();

    /**
     * To switch DataSource
     *
     * @param key the key
     */
    public static void setDataSourceKey(String key) {
        CONTEXT_HOLDER.set(key);
    }

    /**
     * Use master data source.
     */
    public static void useTypeOneMasterDataSource() {
        CONTEXT_HOLDER.set(DataSourceKey.type_one_master.name());
    }
    /**
     * Use master data source.
     */
    public static void useTypeTwoMasterDataSource() {
        CONTEXT_HOLDER.set(DataSourceKey.type_two_master.name());
    }

    /**
     * 当使用只读数据源时通过轮循方式选择要使用的数据源
     */
    public static void useTypeOneSlaveDataSource() {

        try {
            int datasourceKeyIndex = typeOnecounter % typeOneslaveDataSourceKeys.size();
            CONTEXT_HOLDER.set(String.valueOf(typeOneslaveDataSourceKeys.get(datasourceKeyIndex)));
            typeOnecounter++;
        } catch (Exception e) {
            logger.error("Switch slave datasource failed, error message is {}", e.getMessage());
            useTypeOneMasterDataSource();
            e.printStackTrace();
        }
    }

    /**
     * 当使用只读数据源时通过轮循方式选择要使用的数据源
     */
    public static void useTypeTwoSlaveDataSource() {

        try {
            int datasourceKeyIndex = typeTwocounter % typeTwoslaveDataSourceKeys.size();
            CONTEXT_HOLDER.set(String.valueOf(typeTwoslaveDataSourceKeys.get(datasourceKeyIndex)));
            typeTwocounter++;
        } catch (Exception e) {
            logger.error("Switch slave datasource failed, error message is {}", e.getMessage());
            useTypeTwoMasterDataSource();
            e.printStackTrace();
        }
    }

    /**
     * Get current DataSource
     *
     * @return data source key
     */
    public static String getDataSourceKey() {
        return CONTEXT_HOLDER.get();
    }

    /**
     * To set DataSource as default
     */
    public static void clearDataSourceKey() {
        CONTEXT_HOLDER.remove();
    }

    /**
     * Check if give DataSource is in current DataSource list
     *
     * @param key the key
     * @return boolean boolean
     */
    public static boolean containDataSourceKey(String key) {
        return dataSourceKeys.contains(key);
    }
}
